package drds.configuration.mvc.aop;

import drds.configuration.common.Constants;
import drds.configuration.common.DateTimes;
import drds.configuration.mvc.core.Action;
import drds.configuration.mvc.core.Controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 调用Action的容器:包含拦截器和目的方法<br/>
 * 包括Interceptor[]和Action[Controller.Method]
 */
public class ActionExecutor {

    private static final Object[] args = new Object[0];
    private static Logger logger = LoggerFactory.getLogger(ActionExecutor.class);
    private Controller controller;
    private Action action;
    private Interceptor[] interceptors;
    private int length = 0;
    private int index = 0;

    protected ActionExecutor() {
    }

    public ActionExecutor(Action action, Controller controller) {
        this.controller = controller;

        this.action = action;
        // list转数组
        Interceptor[] _s = new Interceptor[action.getInterceptorList().size()];
        action.getInterceptorList().toArray(_s);
        this.interceptors = _s;

        this.length = _s.length;

    }

    public Action getAction() {
        return action;
    }

    public void invoke() {
        long start = System.currentTimeMillis();
        if (length == 0) {
            try {
                // 调用Action中目的方法
                action.getMethod().invoke(controller, args);
            } catch (Exception e) {
                logger.error(e.getMessage());
                if (Constants.devMode) {
                    e.printStackTrace();
                }
                // 获取最近的异常的原因,所以Action内部要仔细的处理异常
                String exceptionMsg = e.getCause().getMessage();
                logger.error(exceptionMsg);
                throw new RuntimeException(exceptionMsg);
            }
        } else {
            if (index <= length - 1) {
                interceptors[index++].doIt(this);
            } else {
                try {
                    // 调用Action中目的方法
                    action.getMethod().invoke(controller, args);
                } catch (Exception e) {
                    logger.error(e.getMessage());
                    if (Constants.devMode) {
                        e.printStackTrace();
                    }
                    // 获取最近的异常的原因,所以Action内部要仔细的处理异常
                    String exceptionMsg = e.getCause().getMessage();
                    logger.error(exceptionMsg);
                    throw new RuntimeException(exceptionMsg);
                }

            }

        }
        long end = System.currentTimeMillis();
        if (end - start > DateTimes.Second * 3) {
            logger.error("Action执行时间超过3秒:" + action.getActionKey());
        }

    }

}
